/***
 * 7-5 列出连通集 (20 分)
给定一个有N个顶点和E条边的无向图，请用DFS和BFS分别列出其所有的连通集。假设顶点从0到N−1编号。进行搜索时，假设我们总是从编号最小的顶点出发，按编号递增的顺序访问邻接点。

输入格式:
输入第1行给出2个整数N(0<N≤10)和E，分别是图的顶点数和边数。随后E行，每行给出一条边的两个端点。每行中的数字之间用1空格分隔。

输出格式:
按照"{ v
1
​
  v
2
​
  ... v
k
​
  }"的格式，每行输出一个连通集。先输出DFS的结果，再输出BFS的结果。

输入样例:
8 6
0 7
0 1
2 0
4 1
2 4
3 5
结尾无空行
输出样例:
{ 0 1 4 2 7 }
{ 3 5 }
{ 6 }
{ 0 1 2 7 4 }
{ 3 5 }
{ 6 }
结尾无空行
***/
#include "stdio.h"
#include "stdlib.h"
#define N 11
int edges[N][N] = {0};
int vis[N];
int stack[N], pos = -1;
void displayStack()
{
    int i;
    printf("{ ");
    for (i = 0; i <= pos; i++)
    {
        if (i < pos)
            printf("%d ", stack[i]);
        else
            printf("%d }\n", stack[i]);
    }
}
void BFS(int first,int n){
    int queue[N];
    int front,tail,cur,i;
    tail=0;
    front=-1;
    queue[tail]=first;
    vis[first]=1;
    while(tail>front){
        front++;
        cur=queue[front];
        pos++;
        stack[pos]=cur;
        for(int i=0;i<n;i++){
            if(!vis[i]&&edges[i][cur]){
                tail++;
                queue[tail]=i;
                vis[i]=1;
            }
        }
    }
}
void DFS(int first, int n)
{
    vis[first] = 1;
    pos++;
    stack[pos] = first;
    for (int i = 0; i < n; i++)
    {
        if (!vis[i] && edges[first][i])
            DFS(i, n);
    }
}
int main(int argc, char const *argv[])
{
    int n, e, i, a, b;

    // freopen("a.txt", "r", stdin);
    scanf("%d%d", &n, &e);
    for (i = 0; i < e; i++)
    {
        scanf("%d%d", &a, &b);
        edges[a][b] = 1;
        edges[b][a] = 1;
    }
    // DFS
    for (i = 0; i < n; i++)
        vis[i] = 0;
    for (i = 0; i < n; i++)
    {
        if (!vis[i])
        {
            DFS(i, n);
            displayStack();
            pos = -1;
        }
    }
    // BFS
    for (i = 0; i < n; i++)
        vis[i] = 0;
    for (i = 0; i < n; i++)
    {
        if (!vis[i])
        {
            BFS(i, n);
            displayStack();
            pos = -1;
        }
    }
    return 0;
}
